/* *
 * Copyright (c) 2004-2005 Mocha Almond Fudge AI, SIT KMUTT. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met:
 * 
 *  o Redistributions of source code must retain the above copyright notice, 
 *    this list of conditions and the following disclaimer. 
 *     
 *  o Redistributions in binary form must reproduce the above copyright notice, 
 *    this list of conditions and the following disclaimer in the documentation 
 *    and/or other materials provided with the distribution. 
 *     
 *  o Neither the name of Mocha Almond Fudge AI, SIT KMUTT nor the names of 
 *    its contributors may be used to endorse or promote products derived 
 *    from this software without specific prior written permission. 
 */
package jboard.model.ai.search;

import java.util.ArrayList;

import jboard.model.BoardPosition;
import jboard.model.Move;

/**
 * Datastructure to be used in MinimaxTree
 * 
 * @author Vashira Ravipanich
 */
public class MinimaxNode {
    public static int MAX = 1;
    
    public static int MIN = 0;
    private BoardPosition boardPosition;
    private ArrayList children;
    private int level;
    private MinimaxNode parentNode;
    private Move toMove;
    private int value; // heuristic value
    
    /**
     * Constructor
     */
    public MinimaxNode() {
        super();
        children = new ArrayList();
    }
    
    /**
     * @param value
     */
    public MinimaxNode(BoardPosition boardPosition, int value,int level) {
        this.boardPosition = boardPosition;
    	this.value = value;
        this.level = level;
        /** internal representation*/
        children = new ArrayList();
        toMove = new Move(); 
    }
	
    /**
     * 
     * @param child
     */
    public void addChild(MinimaxNode child) {
        children.add(child);
		child.setParentNode(this);
    }
    
    /**
     * Override equals
     */
    public boolean equals(Object e) {
        if(e instanceof MinimaxNode) {
            MinimaxNode compare = (MinimaxNode)e;
            if(this.getValue() == compare.getValue()) {
                return true;
            } else {
                return false;
            }
        }
        return false;
    }
    
	/**
	 * @return Returns the boardPosition.
	 */
	public BoardPosition getBoardPosition() {
		return boardPosition;
	}
    
    public MinimaxNode[] getChildren() {
        return (MinimaxNode[])children.toArray(new MinimaxNode[children.size()]);
    }
    
	/**
	 * @return Returns the level.
	 */
	public int getLevel() {
		return level;
	}
    
    /**
     * @return Returns the parentNode.
     */
    public MinimaxNode getParentNode() {
        return parentNode;
    }
    
    public int getState() {
    	int result = MIN;
    	if(getLevel() == 0) {
    		result = MAX;
    	}else if(getLevel()%2 == MIN) {
    		result = MIN;
    	}else if(getLevel()%2 == MAX) {
    		result = MAX;
    	}
    	return result;
    }
	/**
	 * @return Returns the toMove.
	 */
	public Move getToMove() {
		return toMove;
	}
    /**
     * @return Returns the heuristic value.
     */
    public int getValue() {
        return value;
    }
    
    public boolean hasChildren() {
		return children.size()>0;
	}
    
    public void removeChild(MinimaxNode child) {
        children.remove(child);
        child.setParentNode(null);
    }
	/**
	 * @param boardPosition The boardPosition to set.
	 */
	public void setBoardPosition(BoardPosition boardPosition) {
		this.boardPosition = boardPosition;
	}
	
	/**
	 * @param level The level to set.
	 */
	public void setLevel(int level) {
		this.level = level;
	}
    /**
     * @param parentNode The parentNode to set.
     */
    public void setParentNode(MinimaxNode parentNode) {
        this.parentNode = parentNode;
    }
	/**
	 * @param toMove The toMove to set.
	 */
	public void setToMove(Move toMove) {
		this.toMove = toMove;
	}
    /**
     * @param value The heuristic value to set.
     */
    public void setValue(int value) {
        this.value = value;
    }
    
    public String toString() {
    	if(getLevel() == 0) {
    		return "" + getValue() + " level: MAX";
    	}else if(getLevel()%2 == MIN) {
    		return "" + getValue() + " level: MIN";
    	}else if(getLevel()%2 == MAX) {
    		return "" + getValue() + " level: MAX";
    	}
    	return null;
    }
}
